//
//  NetworkManager.swift
//  Kosspot
//
//  Created by 胡辉 on 2025/6/21.
//

import Moya
import RxSwift

class NetworkManager {
    static let shared = NetworkManager()
    private let provider: MoyaProvider<MultiTarget>
    private let jsonDecoder: JSONDecoder
    
    private init(tokenProvider: @escaping () -> String? = { KeychainHelper.getToken() }) {
        let authPlugin = AccessTokenPlugin { _ in
            guard let token = tokenProvider(), !token.isEmpty else {
                debugPrint("缺少 Authentication token")
                return ""
            }
            #if DEBUG
            debugPrint("登录Token : \(token)")
            #endif
            return token
        }
        
        var plugins: [PluginType] = [authPlugin]
        #if DEBUG
        plugins.append(NetworkLoggerPlugin(configuration: .init(logOptions: .default)))
        #endif
        
        provider = MoyaProvider<MultiTarget>(plugins: plugins)
        
        jsonDecoder = JSONDecoder()
        jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
        jsonDecoder.dateDecodingStrategy = .iso8601
    }
    
    func request<T: BaseResponseProtocol>(_ target: MultiTarget, responseType: T.Type) -> Observable<T> {
            return provider.rx.request(target)
                .asObservable()
                .filterSuccessfulStatusCodes()
                .catch { error in
                    throw NetworkError.requestFailed(description: error.localizedDescription)
                }
                .flatMap { [weak self] response -> Observable<T> in
                    guard let self = self else {
                        return Observable.error(NetworkError.invalidResponse(statusCode: response.statusCode))
                    }
                    
                    do {
                        let responseModel = try self.jsonDecoder.decode(T.self, from: response.data)
                        
                        if responseModel.code != 200 {
                            if responseModel.code == 401 || responseModel.code == 403 {
                                AppState.shared.logout()
                                throw NetworkError.unauthorized
                            }
                            throw NetworkError.serverError(
                                code: responseModel.code,
                                message: responseModel.msg
                            )
                        }
                        
                        return Observable.just(responseModel)
                    } catch let error as DecodingError {
                        print("🔥 JSON解码失败: \(error)")
                        throw NetworkError.decodingFailed
                    } catch {
                        throw error
                    }
                }
                .catch { error in
                    if let networkError = error as? NetworkError {
                        return Observable.error(networkError)
                    } else {
                        return Observable.error(NetworkError.requestFailed(description: error.localizedDescription))
                    }
                }
        }
        
        func requestField<T: Decodable>(_ target: MultiTarget, field: String) -> Observable<T> {
            return request(target, responseType: SimpleResponse.self)
                .flatMap { response in
                    let mirror = Mirror(reflecting: response)
                    
                    for child in mirror.children {
                        if child.label == field, let value = child.value as? T {
                            return Observable.just(value)
                        }
                    }
                    
                    throw NetworkError.missingRequiredField(field: field)
                }
        }
    
//    func login(username: String, password: String, code: String, uuid: String) -> Single<LoginResponse> {
//        provider.rx.request(MultiTarget(ApiService.login(username: username, password: password, code: code, uuid: uuid)))
//            .filterSuccessfulStatusCodes()
//            .map(LoginResponse.self)
//    }
//    
//    
//    func sendSMCcode(mobile: String, scene: String) -> Single<SendEMCResponse> {
//        provider.rx.request(MultiTarget(ApiService.sendSMCcode(mobile: mobile, scene: scene)))
//            .filterSuccessfulStatusCodes()
//            .map(SendEMCResponse.self)
//    }
//    
//    func loginByCode(mobile: String, code: String) -> Single<PhoneLoginResponse> {
//        provider.rx.request(MultiTarget(ApiService.loginByCode(mobile: mobile, code: code)))
//            .filterSuccessfulStatusCodes()
//            .map(PhoneLoginResponse.self)
//    }
//    
//    func refreshCaptchaImage() -> Single<CaptchaImage> {
//        provider.rx.request(MultiTarget(ApiService.captchaImage))
//            .filterSuccessfulStatusCodes()
//            .map(CaptchaImage.self)
//            
//    }
//    
//    func updatePassWord(newPassword:String,oldPassword:String) -> Single<UpdatePasswordResponse>{
//        provider.rx.request(MultiTarget(ApiService.updatePwd(newPassword: newPassword, oldPassword: oldPassword)))
//            .filterSuccessfulStatusCodes()
//            .map(UpdatePasswordResponse.self)
//    }
    
    
//    func userprofile() -> Single<UserProfileResponse> {
//        provider.rx.request(MultiTarget(ApiService.userProfile))
//            .filterSuccessfulStatusCodes()
//            .map(UserProfileResponse.self)
//    }
    
//    func fitnessList() -> Single<FitnesslistResponse>{
//        provider.rx.request(MultiTarget(ApiService.fitnessList))
//            .filterSuccessfulStatusCodes()
//            .map(FitnesslistResponse.self)
//    }
    
//    func uploadAvatar(avatarUrl:String) -> Single<AvatarResponse>{
//        provider.rx.request(MultiTarget(ApiService.profileAvatar(avatarUrl: avatarUrl)))
//            .filterSuccessfulStatusCodes()
//            .map(AvatarResponse.self)
//    }
    
//    func updateUserInfo(nickname: String, gender: Int, birthday: String, height: String?, weight: String?) -> Single<CommonResponse> {
//        provider.rx.request(MultiTarget(ApiService.updateUserInfo(nickname: nickname, gender: gender, birthday: birthday, height: height, weight: weight)))
//            .filterSuccessfulStatusCodes()
//            .map(CommonResponse.self)
//    }

//    func  dynamicAdd(userId: Int, content: String, address:String, mediaUrls:[String], createTime:Int) -> Single<GeneralResponse> {
//        provider.rx.request(MultiTarget(ApiService.dynamicAdd(userId: userId, content: content, address: address, mediaUrls: mediaUrls, createTime: createTime)))
//            .filterSuccessfulStatusCodes()
//            .map(GeneralResponse.self)
//    }
//    
//    func getDynamicList() -> Single<SportMomentResponse> {
//        provider.rx.request(MultiTarget(ApiService.dynamicList))
//            .filterSuccessfulStatusCodes()
//            .map(SportMomentResponse.self)
//            
//    }
//    
//    func dynamicLike(dynamicId:Int) ->Single<GeneralResponse>{
//        provider.rx.request(MultiTarget(ApiService.dynamicLike(dynamicId: dynamicId)))
//            .filterSuccessfulStatusCodes()
//            .map(GeneralResponse.self)
//    }
//    
//    
//    func dynamicUnlike(dynamicId:Int) ->Single<GeneralResponse>{
//        provider.rx.request(MultiTarget(ApiService.dynamicUnlike(dynamicId: dynamicId)))
//            .filterSuccessfulStatusCodes()
//            .map(GeneralResponse.self)
//    }
    
//    func logout() -> Single<GeneralResponse> {
//        provider.rx.request(MultiTarget(ApiService.logout))
//            .filterSuccessfulStatusCodes()
//            .map(GeneralResponse.self)
//    }
}

